<html>
<head><meta charset="utf-8"><title>Where’s my undefined behavior when string interning? · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html">Where’s my undefined behavior when string interning?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="223754384"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223754384" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223754384">(Jan 23 2021 at 15:17)</a>:</h4>
<p>I'm playing around with a little string interning code, but Miri complains about <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=264adecd7e7ae976e714f6e5ad77d214">this code</a>. The error is only reported when dropping the value:</p>
<div class="codehilite"><pre><span></span><code>error: Undefined Behavior: trying to reborrow for SharedReadOnly at alloc1848, but parent tag &lt;4135&gt; does not have an appropriate item in the borrow stack
   --&gt; /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/unique.rs:118:18
    |
118 |         unsafe { &amp;*self.as_ptr() }
    |                  ^^^^^^^^^^^^^^^ trying to reborrow for SharedReadOnly at alloc1848, but parent tag &lt;4135&gt; does not have an appropriate item in the borrow stack
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
</code></pre></div>
<p>I'm not seeing where I'd be causing the problem.</p>
<p>(I'll be on and off the computer for the next bit, so no hurry in replying)</p>



<a name="223755185"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755185" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755185">(Jan 23 2021 at 15:35)</a>:</h4>
<p>The borrow gets invalidated when you add <code>ll</code> to the linked list. Borrowing from the linked list seems to work:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="n">ll</span><span class="p">.</span><span class="n">push_front</span><span class="p">(</span><span class="n">piece</span><span class="p">);</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">raw_str</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RawStr</span><span class="p">(</span><span class="n">ll</span><span class="p">.</span><span class="n">iter</span><span class="p">().</span><span class="n">next</span><span class="p">().</span><span class="n">unwrap</span><span class="p">().</span><span class="n">as_ptr</span><span class="p">(),</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="n">len</span><span class="p">());</span><span class="w"></span>
</code></pre></div>



<a name="223755446"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755446" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755446">(Jan 23 2021 at 15:40)</a>:</h4>
<p>You mean when <code>piece</code> gets added to <code>ll</code>. I feel like I've seen this kind of code in the wild before - is there a way to keep pointers to the <code>T</code> in <code>Box&lt;T&gt;</code> alive when you move the <code>Box</code>?</p>



<a name="223755451"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755451" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755451">(Jan 23 2021 at 15:40)</a>:</h4>
<p>Hmm <span aria-label="thinking" class="emoji emoji-1f914" role="img" title="thinking">:thinking:</span>. But the memory itself should be off in the heap at a stable address (via <code>Box</code>), yeah?</p>



<a name="223755483"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755483" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755483">(Jan 23 2021 at 15:41)</a>:</h4>
<p>In hindsight it makes sense - when you move the box you are re-asserting unique access and all old pointers become invalidated (even though the data is still at that location)</p>



<a name="223755486"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755486" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755486">(Jan 23 2021 at 15:41)</a>:</h4>
<p><code>Box</code> is special. A <code>Box</code> counts as a unique borrow as far as I know.</p>



<a name="223755644"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755644" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755644">(Jan 23 2021 at 15:45)</a>:</h4>
<p>You are saying “pointer“, but don’t you mean reference? That’s why I am using raw pointers here.</p>



<a name="223755724"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755724" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755724">(Jan 23 2021 at 15:47)</a>:</h4>
<p>This is part of the reason I’m confused; when the linked list is dropped it should be the unique owner of the data</p>



<a name="223755736"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755736" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dániel Buga <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755736">(Jan 23 2021 at 15:47)</a>:</h4>
<p>Not sure if this is UB, but ll gets dropped before set, so set can contain a pointer to freed memory</p>



<a name="223755799"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755799" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755799">(Jan 23 2021 at 15:48)</a>:</h4>
<p>The moment you move the <code>Box</code> into the linked list, all raw pointers to it get invalidated.</p>



<a name="223755820"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755820" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755820">(Jan 23 2021 at 15:49)</a>:</h4>
<p>The only difference between pointers and references here is that one of them is checked by the compiler and the other is checked by miri</p>



<a name="223755831"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755831" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755831">(Jan 23 2021 at 15:49)</a>:</h4>
<p>they aren't a get out of jail free card for the borrow checker rules</p>



<a name="223755882"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755882" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755882">(Jan 23 2021 at 15:50)</a>:</h4>
<p>Pointers do also allow aliasing, but if the reference from which it is derived gets invalidated or used, all raw pointers get invalidated.</p>



<a name="223755883"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755883" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755883">(Jan 23 2021 at 15:50)</a>:</h4>
<p><span class="user-mention" data-user-id="334260">@Dániel Buga</span>  Ugh, you are right. I copied from a struct where the drop order is the other way, so that shouldn’t be a problem in my original location.</p>



<a name="223755899"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755899" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dániel Buga <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755899">(Jan 23 2021 at 15:51)</a>:</h4>
<p>Actually, miri points at the drop of ll, so I'm not sure if this is the actual UB, but still something wrong</p>



<a name="223755967"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755967" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755967">(Jan 23 2021 at 15:52)</a>:</h4>
<p><span class="user-mention" data-user-id="133247">@bjorn3</span> I don't want a pointer to the box though, I want the data inside the box￼</p>



<a name="223755975"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223755975" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223755975">(Jan 23 2021 at 15:52)</a>:</h4>
<p>You can use <code>Box::into_raw</code> and <code>Box::from_raw</code> when you want to drop it again.</p>



<a name="223756007"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756007" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dániel Buga <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756007">(Jan 23 2021 at 15:53)</a>:</h4>
<blockquote>
<p>Box::from_raw when you want to drop it again</p>
</blockquote>
<p><del>or ptr::drop_in_place, I think?</del> ugh, no</p>



<a name="223756070"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756070" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756070">(Jan 23 2021 at 15:54)</a>:</h4>
<p>When you create the pointer here</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">raw_str</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RawStr</span><span class="p">(</span><span class="n">piece</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">(),</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="n">len</span><span class="p">());</span><span class="w"></span>
</code></pre></div>
<p>the pointer has a lifetime that is tied to the borrow of <code>piece</code>. When you later move <code>piece</code> here</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="w">        </span><span class="n">ll</span><span class="p">.</span><span class="n">push_front</span><span class="p">(</span><span class="n">piece</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<p>the pointer becomes invalidated, but that's not immediately an issue, it's just a dangling pointer that you returned. It's not actually a stack discipline violation yet, because you might never use the mut pointer you passed to the linked list. So you use the "dangling" pointer and it invalidates the pointer in the linked list instead, and then when the linked list is dropped we definitely have an XYXY usage pattern and miri declares UB</p>



<a name="223756159"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756159" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756159">(Jan 23 2021 at 15:56)</a>:</h4>
<p>Creating dangling pointers (not references) is fine, as long as you never use them while they are dangling</p>



<a name="223756235"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756235" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756235">(Jan 23 2021 at 15:58)</a>:</h4>
<p>Perhaps that explains why removing the usage of the unsafe code via the hashmap calling <code>Hash</code> causes Miri to be OK￼ — that's the "Y" usage.</p>



<a name="223756264"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756264" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756264">(Jan 23 2021 at 15:59)</a>:</h4>
<p>I see a dotted boxed [OBJ] around your last two comments jake but it looks apropos to the topic <span aria-label="grinning" class="emoji emoji-1f600" role="img" title="grinning">:grinning:</span></p>



<a name="223756320"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756320" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dániel Buga <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756320">(Jan 23 2021 at 16:00)</a>:</h4>
<p>unless it's unintended heap allocation <span aria-label="stuck out tongue" class="emoji emoji-1f61b" role="img" title="stuck out tongue">:stuck_out_tongue:</span></p>



<a name="223756326"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756326" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756326">(Jan 23 2021 at 16:00)</a>:</h4>
<p>Does switching to a raw pointer instead of box fix the problem because it won’t assume that it’s a unique pointer￼￼?</p>



<a name="223756351"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756351" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756351">(Jan 23 2021 at 16:01)</a>:</h4>
<p>and thus Miri won’t see conflicting usages of it during its time in existence. ￼</p>



<a name="223756356"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756356" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756356">(Jan 23 2021 at 16:01)</a>:</h4>
<p>Ah yeah that should work, just make it a mut pointer</p>



<a name="223756370"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756370" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756370">(Jan 23 2021 at 16:01)</a>:</h4>
<p>just imagine it's a refcell</p>



<a name="223756444"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756444" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756444">(Jan 23 2021 at 16:03)</a>:</h4>
<p>or use bjorn's suggestion, which you can also write as first pushing the vector into the linked list, getting the head and using that to form the pointer</p>



<a name="223756557"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756557" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756557">(Jan 23 2021 at 16:05)</a>:</h4>
<p>like this</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="w">    </span><span class="n">set</span><span class="p">.</span><span class="n">get_or_insert_with</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="o">|</span><span class="n">s</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">ll</span><span class="p">.</span><span class="n">push_front</span><span class="p">(</span><span class="fm">vec!</span><span class="p">[</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="mi">1024</span><span class="p">].</span><span class="n">into_boxed_slice</span><span class="p">());</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">piece</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ll</span><span class="p">.</span><span class="n">front_mut</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span><span class="w"></span>
<span class="w">        </span><span class="n">piece</span><span class="p">[</span><span class="o">..</span><span class="n">s</span><span class="p">.</span><span class="n">len</span><span class="p">()].</span><span class="n">copy_from_slice</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">as_bytes</span><span class="p">());</span><span class="w"></span>
<span class="w">        </span><span class="n">RawStr</span><span class="p">(</span><span class="n">piece</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">(),</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="n">len</span><span class="p">())</span><span class="w"></span>
<span class="w">    </span><span class="p">});</span><span class="w"></span>
</code></pre></div>



<a name="223756581"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756581" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756581">(Jan 23 2021 at 16:05)</a>:</h4>
<p>That has the annoying panic that can never happen though</p>



<a name="223756625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756625">(Jan 23 2021 at 16:06)</a>:</h4>
<p>That actually seems like an API hole in vec and linked list</p>



<a name="223756638"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756638" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756638">(Jan 23 2021 at 16:06)</a>:</h4>
<p>those push methods could totally return <code>&amp;mut T</code></p>



<a name="223756677"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756677" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756677">(Jan 23 2021 at 16:07)</a>:</h4>
<p>if you're lucky the panic will get optimized out, if not there's always <code>std::hint::unreachable_unchecked()</code></p>



<a name="223756737"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756737" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756737">(Jan 23 2021 at 16:08)</a>:</h4>
<p>always a great way to tell the reader you mean business <span aria-label="grinning face with smiling eyes" class="emoji emoji-1f601" role="img" title="grinning face with smiling eyes">:grinning_face_with_smiling_eyes:</span></p>



<a name="223756767"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756767" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756767">(Jan 23 2021 at 16:09)</a>:</h4>
<p>I’m on mobile right now, but I’d be worried about what would happen if I were to push one chunk into the link list then get the pointer then push another chunk and get its pointer</p>



<a name="223756846"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756846" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756846">(Jan 23 2021 at 16:11)</a>:</h4>
<p>Seems like that would trigger the same problem as the first chunk would get moved again</p>



<a name="223756902"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756902" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756902">(Jan 23 2021 at 16:12)</a>:</h4>
<p>Ah yeah that's going to be a problem with <code>LinkedList&lt;Box&lt;T&gt;&gt;</code>. Not always, it depends on exactly what the linked list does, but most likely you'll get the same issue: if there is a reallocation it will move the box and that will assert ownership of the T and break your pointers</p>



<a name="223756907"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756907" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756907">(Jan 23 2021 at 16:12)</a>:</h4>
<p>which I think is an argument for using <code>LinkedList&lt;*mut T&gt;</code></p>



<a name="223756916"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223756916" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223756916">(Jan 23 2021 at 16:12)</a>:</h4>
<p>because that way the linked list can't break your pointers even if it moves stuff around</p>



<a name="223757010"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223757010" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223757010">(Jan 23 2021 at 16:15)</a>:</h4>
<p>(and to clarify, by "move the box" I mean do a move operation on a variable of type <code>Box&lt;T&gt;</code>, not move the <code>T</code> data which has your pointers)</p>



<a name="223757359"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223757359" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223757359">(Jan 23 2021 at 16:23)</a>:</h4>
<p>This appears to pass miri, even with the original out-of-order access pattern, just using <code>*mut</code> instead of <code>Box</code>:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">HashSet</span>::<span class="n">new</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">ll</span>: <span class="nc">LinkedList</span><span class="o">&lt;*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">]</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">LinkedList</span>::<span class="n">new</span><span class="p">();</span><span class="w"></span>

<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"hello"</span><span class="p">;</span><span class="w"></span>

<span class="w">    </span><span class="n">set</span><span class="p">.</span><span class="n">get_or_insert_with</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="o">|</span><span class="n">s</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">piece</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="mi">1024</span><span class="p">].</span><span class="n">into_boxed_slice</span><span class="p">();</span><span class="w"></span>
<span class="w">        </span><span class="n">piece</span><span class="p">[</span><span class="o">..</span><span class="n">s</span><span class="p">.</span><span class="n">len</span><span class="p">()].</span><span class="n">copy_from_slice</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">as_bytes</span><span class="p">());</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">raw_str</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RawStr</span><span class="p">(</span><span class="n">piece</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">(),</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="n">len</span><span class="p">());</span><span class="w"></span>

<span class="w">        </span><span class="n">ll</span><span class="p">.</span><span class="n">push_front</span><span class="p">(</span><span class="nb">Box</span>::<span class="n">into_raw</span><span class="p">(</span><span class="n">piece</span><span class="p">));</span><span class="w"></span>

<span class="w">        </span><span class="n">raw_str</span><span class="w"></span>
<span class="w">    </span><span class="p">});</span><span class="w"></span>
<span class="w">    </span><span class="k">for</span><span class="w"> </span><span class="n">piece</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">ll</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">from_raw</span><span class="p">(</span><span class="n">piece</span><span class="p">);</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="223757374"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223757374" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223757374">(Jan 23 2021 at 16:23)</a>:</h4>
<p>the manual destructor bit isn't great but I guess you can encapsulate that</p>



<a name="223757445"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223757445" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223757445">(Jan 23 2021 at 16:25)</a>:</h4>
<p>I like that you thought I’d have a linked list that I only ever pushed one value into 😂</p>



<a name="223757504"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223757504" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223757504">(Jan 23 2021 at 16:26)</a>:</h4>
<p>I mean, this is your real application, right?</p>



<a name="223757523"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223757523" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223757523">(Jan 23 2021 at 16:27)</a>:</h4>
<p>it seems a little complicated but hey, maybe storing "hello" is really important to you</p>



<a name="223757539"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223757539" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223757539">(Jan 23 2021 at 16:27)</a>:</h4>
<p>Ok, cool. I’m not scared of using a raw pointer. And the fact that box has <code>Unique</code> within it and I was not treating it as unique does clarify the root of my misunderstanding</p>



<a name="223757599"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Where%E2%80%99s%20my%20undefined%20behavior%20when%20string%20interning%3F/near/223757599" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Where.E2.80.99s.20my.20undefined.20behavior.20when.20string.20interning.3F.html#223757599">(Jan 23 2021 at 16:28)</a>:</h4>
<p>Thanks all! I’ll try applying these lessons back to the real code and see how I fare.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>